package com.example.acharten;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;

import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;

public class CurveChart {
	private String title;//标题
	private String activityTitle;//Activity 标题
	private String xTitle; //x轴标题
	private String yTitle; //y轴标题
	private Integer yMax; //y轴最大值
	private Integer yMin; //y轴最小值
	private Integer xMax; //x最大值
	private Integer xMin; //x最小值
	private int[] colors;
	private Color axesColor;
	private Color lablesColor; //x，y显示值的颜色
	private Integer xLables;//x轴等分
	private Integer yLables;//y轴等分
	private PointStyle[] styles; //曲线坐标点样式
	private boolean applyBackGroundColor; //是否设置背景色
	private int backGroundColor; //背景颜色
	private boolean showGird; //是否显示网格
	private boolean zoomButtonsVisible; //是否显示缩放功能
	private List<Map<String, Map<String, Object>>> dataContents;  //你的数据内容
	private List<Map<String, Object>> xValues;//x,y坐标
	
	protected XYMultipleSeriesRenderer buildRenderer(int[] colors,
			PointStyle[] styles) {
		//图表显示渲染器,如颜色样式等等......
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		setRenderer(renderer, colors, styles);
		return renderer;
	}

	public XYMultipleSeriesRenderer getRenderer() {
		//一些随机默认设置要用到
		Random random = new Random();
		/**
		 * 设置一些默认值
		 */
		if (title == null) {
			title = "未知标题";
		}
		
		if (xTitle == null) {
			xTitle = "X";
		}
		
		if (yTitle == null) {
			yTitle = "Y";
		}
		
		if (yMin == null) {
			yMin = 0;
		}
		
		if (yMax == null) {
			yMax = 100;
		}
		
		if (applyBackGroundColor == false) {
			backGroundColor = Color.BLACK;
		}
		//6种颜色 曲线多的话 添加就行了
		
		//还是随机好了，也可以自己加
		if (colors == null) {
//			colors = new int[] { Color.BLUE, Color.GREEN, Color.CYAN,
//					Color.YELLOW, Color.RED, Color.LTGRAY};
			  
			colors = new int[dataContents.get(0).size()];
			
			for (int i = 0; i < colors.length; i++) {
				colors[i] = Color.rgb(random.nextInt()*128+128 ,
						random.nextInt()*128+128, random.nextInt()*128+128);
			}
		}
		//只有5种坐标标记风格，多就只能重复了，这点有点不好
		if (styles == null) {
			PointStyle[] pointStyles = PointStyle.values();
			PointStyle style = null;
			styles = new PointStyle[dataContents.get(0).size()];
			
			for (int i = 0; i < styles.length; i++) {
				int rn = random.nextInt(pointStyles.length);
				style = pointStyles[rn];
				styles[i] = style;
			}
//			styles = new PointStyle[]{PointStyle.DIAMOND, PointStyle.TRIANGLE, PointStyle.SQUARE
//			,PointStyle.TRIANGLE, PointStyle.CIRCLE, PointStyle.SQUARE};
		}
			
		XYMultipleSeriesRenderer renderer = buildRenderer(colors, styles);
		int length = renderer.getSeriesRendererCount();
		for (int i = 0; i < length; i++) {
			((XYSeriesRenderer) renderer.getSeriesRendererAt(i))
					.setFillPoints(true);
		}

		setChartSettings(renderer, title, xTitle,
				yTitle, 1, xValues.get(0).size(),
				yMin, yMax, Color.LTGRAY, Color.LTGRAY);
		renderer.setXLabels(xLables);
		renderer.setYLabels(yLables);
		//因为下一个注释的原因， 所以这里就也不设置了
//		renderer.setChartValuesTextSize(15);
		renderer.setShowGrid(true);
		//已经被官方废弃，显示坐标上的y值 好像有很多问题， 有的值显示不出来，还会导致内部数组越界问题
//		renderer.setDisplayChartValues(true);/
		renderer.setXLabelsAlign(Align.RIGHT);
		renderer.setYLabelsAlign(Align.RIGHT);
		renderer.setApplyBackgroundColor(applyBackGroundColor);
		renderer.setBackgroundColor(backGroundColor);
		renderer.setZoomButtonsVisible(true);
		return renderer;
	}

	/**
	 * 图表显示渲染器相关设置
	 * @param renderer
	 * @param colors
	 * @param styles
	 */
	public void setRenderer(XYMultipleSeriesRenderer renderer, int[] colors,
			PointStyle[] styles) {
		renderer.setAxisTitleTextSize(16);
		renderer.setChartTitleTextSize(20);
		renderer.setLabelsTextSize(15);
		renderer.setLegendTextSize(15);
		renderer.setPointSize(5f);
		renderer.setMargins(new int[] { 20, 30, 15, 20 });
		int length = colors.length;
		for (int i = 0; i < length; i++) {
			XYSeriesRenderer r = new XYSeriesRenderer();
			r.setColor(colors[i]);
			r.setPointStyle(styles[i]);
			renderer.addSeriesRenderer(r);
		}
		
		renderer.setBarSpacing(0.001);
		renderer.setAxesColor(Color.BLUE);
	}

	/**
	 * 图形设置相关参数
	 * @author lxj
	 * @param renderer
	 * @param title
	 * @param xTitle
	 * @param yTitle
	 * @param xMin
	 * @param xMax
	 * @param yMin
	 * @param yMax
	 * @param axesColor
	 * @param labelsColor
	 * 
	 */
	public void setChartSettings(XYMultipleSeriesRenderer renderer,
			String title, String xTitle, String yTitle, double xMin,
			double xMax, double yMin, double yMax, int axesColor,
			int labelsColor) {
		renderer.setChartTitle(title);
		renderer.setXTitle(xTitle);
		renderer.setYTitle(yTitle);
		renderer.setXAxisMin(xMin);
		renderer.setXAxisMax(xMax);
		renderer.setYAxisMin(yMin);
		renderer.setYAxisMax(yMax);
		renderer.setAxesColor(axesColor);
		renderer.setLabelsColor(labelsColor);
	}

	protected XYMultipleSeriesDataset buildDataset(String[] titles,
			List<Map<String,Object>> xValues, List<double[]> yValues) {
		//图表数据渲染器设置
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		addXYSeries(dataset, titles, xValues, yValues, 0);
		return dataset;
	}

	/**
	 * 画出每条曲线
	 * @param dataset
	 * @param titles
	 * @param xValues
	 * @param yValues
	 * @param scale
	 */
	public void addXYSeries(XYMultipleSeriesDataset dataset, String[] titles,
			List<Map<String, Object>> xValues, List<double[]> yValues, int scale) {
		//画多少条去曲线
		int length = titles.length;
		for (int i = 0; i < length; i++) {
			/**
			 * 曲线名称及 填充x轴，y轴后
			 * 连成线
			 */
			XYSeries series = new XYSeries(titles[i], scale);
			Iterator<Entry<String, Object>> xValuesIt = xValues.get(i).entrySet().iterator();
			
			while (xValuesIt.hasNext()) {
				Entry<String, Object> eso = xValuesIt.next();
				/**
				 * eso.getKey())为x轴的值
				 * Double.parseDouble(eso.getValue().toString())为y轴的值
				 */
				series.add(Double.parseDouble(eso.getKey()), Double.parseDouble(eso.getValue().toString()));
			}
			
			dataset.addSeries(series);
		}
	}

	/**
	 * @author lxj
	 * @param dataContents
	 * @return
	 */
	public XYMultipleSeriesDataset getDataset(List<Map<String, Map<String, Object>>> dataContents) {
		//曲线参数：(List<Map<曲线名称, Map<x轴的值, y轴的值>>  曲线数量就是曲线名称的数量
		String[] curveNames = new String[dataContents.get(0).size()];
		//曲线名称
		String curveName = null;
		//一条曲线单个y轴的值
		double yValue = 0.00;
		//一条曲线的y轴值
		double[] yValuesArr = null;
		//一条曲线的y轴所有值数组的大小
		int yValuesLength = 0;
		//所有曲线的y轴值
		List<double[]> yValues = new ArrayList<double[]>();
		//x，y坐标
		xValues = new ArrayList<Map<String, Object>>();
		//每条曲线的所有x，y坐标值
		Map<String, Object> dataContentMaps = new HashMap<String, Object>();
		//曲线名称，及曲线对应x，y的数据
		Map<String, Map<String,Object>> dataContent = dataContents.get(0);
		//没什么，遍历
		Iterator<Entry<String, Map<String, Object>>> it = dataContent.entrySet().iterator();
		
		int x = 0;
		while (it.hasNext()) {
			Entry<String, Map<String, Object>> content = it.next();
			//曲线名称
			curveName = content.getKey();
			//一条曲线对应的所有X，y轴值
			dataContentMaps = content.getValue();
			Iterator<Entry<String, Object>> itXValue = dataContentMaps.entrySet().iterator();
			//先遍历，确定每条曲线y轴值的数组长度
			while (itXValue.hasNext()) {
				itXValue.next();
				yValuesLength++;
			}
			//创建每条曲线y轴值的数组
			yValuesArr = new double[yValuesLength];
			//因为上面设置要确定每条曲线对应的y轴值数组的大小，先遍历了一遍，以便下面y轴值数组存放数据
			itXValue = dataContentMaps.entrySet().iterator();
			int j = 0;
			while (itXValue.hasNext()) {
				Entry<String, Object>  data = itXValue.next();
				//一条曲线单个y轴的值
				yValue = Double.parseDouble(data.getValue().toString());
				//一条曲线所有y轴的值
				yValuesArr[j] = yValue;
				j++;

			}
			
			//每条曲线的X，y值
			xValues.add(dataContentMaps);
			//每条曲线的y轴值
			yValues.add(yValuesArr);
			//曲线名称
			curveNames[x] =curveName;
			x++;
		}
		
		/**
		 * 图表数据渲染器填充数据
		 */
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		dataset = buildDataset(curveNames, xValues, yValues);
		return dataset;
	}

	
	public Intent createLineChartIntent(Context context, List<Map<String, Map<String, Object>>> dataContents
			,String title, String xTitle, String yTitle, Integer yMin, Integer yMax, Integer yLables,
			Integer xLables, boolean applyBackGroundColor, int backGroundColor, int[] colors, PointStyle[] styles) {
		this.dataContents = dataContents;
		this.title = title;
		this.xTitle = xTitle;
		this.yTitle = yTitle;
		this.yMin = yMin;
		this.yMax = yMax;
		this.yLables = yLables;
		this.xLables = xLables;
		this.applyBackGroundColor = applyBackGroundColor;
		this.backGroundColor = backGroundColor;
		this.colors = colors;
		this.styles = styles;
	    Intent intent = ChartFactory.getLineChartIntent(context, getDataset(getDataContents()),
	            getRenderer(), title);
//	    Intent intent = ChartFactory.getCubicLineChartIntent(context, getDataset(getDataContents()),
//	            getRenderer(), 0.5f,title);
	    return intent;
	}
	public int[] getColors() {
		return colors;
	}

	public void setColors(int[] colors) {
		this.colors = colors;                                                     
	}

	public PointStyle[] getStyles() {
		return styles;
	}

	public void setStyles(PointStyle[] styles) {
		this.styles = styles;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getActivityTtle() {
		return activityTitle;
	}

	public void setActivityTitle(String activityTitle) {
		this.activityTitle = activityTitle;
	}

	public String getxTitle() {
		return xTitle;
	}

	public void setxTitle(String xTitle) {
		this.xTitle = xTitle;
	}

	public String getyTitle() {
		return yTitle;
	}

	public void setyTitle(String yTitle) {
		this.yTitle = yTitle;
	}

	public Integer getyMax() {
		return yMax;
	}

	public void setyMax(Integer yMax) {
		this.yMax = yMax;
	}

	public Integer getyMin() {
		return yMin;
	}

	public void setyMin(Integer yMin) {
		this.yMin = yMin;
	}

	public Integer getxMax() {
		return xMax;
	}

	public void setxMax(Integer xMax) {
		this.xMax = xMax;
	}

	public Integer getxMin() {
		return xMin;
	}

	public void setxMin(Integer xMin) {
		this.xMin = xMin;
	}

	public Color getAxesColor() {
		return axesColor;
	}

	public void setAxesColor(Color axesColor) {
		this.axesColor = axesColor;
	}

	public Color getLablesColor() {
		return lablesColor;
	}

	public void setLablesColor(Color lablesColor) {
		this.lablesColor = lablesColor;
	}

	public Integer getxLables() {
		return xLables;
	}

	public void setxLables(Integer xLables) {
		this.xLables = xLables;
	}

	public Integer getyLables() {
		return yLables;
	}

	public void setyLables(Integer yLables) {
		this.yLables = yLables;
	}

	public boolean isApplyBackGroundColor() {
		return applyBackGroundColor;
	}

	public void setApplyBackGroundColor(boolean applyBackGroundColor) {
		this.applyBackGroundColor = applyBackGroundColor;
	}

	public boolean isShowGird() {
		return showGird;
	}

	public void setShowGird(boolean showGird) {
		this.showGird = showGird;
	}

	public boolean isZoomButtonsVisible() {
		return zoomButtonsVisible;
	}

	public void setZoomButtonsVisible(boolean zoomButtonsVisible) {
		this.zoomButtonsVisible = zoomButtonsVisible;
	}

	public List<Map<String, Map<String, Object>>> getDataContents() {
		return dataContents;
	}

	public void setDataContents(List<Map<String, Map<String, Object>>> dataContents) {
		this.dataContents = dataContents;
	}


	public List<Map<String, Object>> getxValues() {
		return xValues;
	}

	public void setxValues(List<Map<String, Object>> xValues) {
		this.xValues = xValues;
	}

	public int getBackGroundColor() {
		return backGroundColor;
	}

	public void setBackGroundColor(int backGroundColor) {
		this.backGroundColor = backGroundColor;
	}

	public String getActivityTitle() {
		return activityTitle;
	}
}
